﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Beeldbankmvc.Code;

namespace Beeldbankmvc.Models
{
    public class StarRatingRepository
    {
        BeeldbankLinqDataContext db = new BeeldbankLinqDataContext();

        public IQueryable<BEELDBANK_BEOORDEEL> FindAll()
        {
            return db.BEELDBANK_BEOORDEELs;
        }

        public StarAverageModel GetTopRatedMediaObject()
        {
            //SELECT 
            //AVG(Score) AS Average, MediaObjectId
            //FROM dbo.BEELDBANK_BEOORDEEL BB
            //GROUP BY MediaObjectId
            //order by Average desc
            var topItems = (from bb in db.BEELDBANK_BEOORDEELs
                           group bb by new
                           {
                               MediaObjectId = bb.MediaObjectId,
                               Score = bb.Score
                           } into grouped
                           select new
                           {
                               MediaObjectId = grouped.Key.MediaObjectId,
                               AverageValue = grouped.Average(g => g.Score)
                           } into c
                           orderby c.AverageValue descending
                           select new
                           {
                               c.MediaObjectId,
                               c.AverageValue
                           }).Take(250);

            StarAverageModel averageModel = new StarAverageModel();

            // Fetch random record from list
            Random r = new Random();

            // Safety built in
            if (topItems.Count() >= 1)
            {
                int randomNumber = r.Next(topItems.Count() - 1);
                int i = 0;
                foreach (var item in topItems)
                {
                    if (i == randomNumber)
                    {
                        averageModel.AverageValue = item.AverageValue;
                        averageModel.MediaObjectId = item.MediaObjectId;
                    }
                    i++;
                }
            }
            return averageModel;            
        }

        public StarRatingModel FindOne(int mediaObjectId)
        {
            StarRatingModel ratingModel = new StarRatingModel();
            var rating = from p in db.BEELDBANK_BEOORDEEL_SELECT(mediaObjectId)
                         select p;
            
            if (!LinqHelper.IsEmpty(rating))
            {
                // todo: clean this up
                // Redo the query because IsEmpty check results in not being able to do .Single() query
                var ratingObject = from p in db.BEELDBANK_BEOORDEEL_SELECT(mediaObjectId)
                    select new
                    {
                        AantalBeoordeeld = p.AantalBeoordeeld,
                        GemiddeldAantalSterren = p.GemiddeldAantalSterren,
                        TotaalAantalSterren = p.TotaalAantalSterren,
                        MediaObjectId = p.MediaObjectId
                    };
                
                var rat = ratingObject.Single();

                ratingModel.votes = Convert.ToInt32(rat.AantalBeoordeeld);
                ratingModel.sum = Convert.ToInt32(rat.TotaalAantalSterren);
                ratingModel.avg = Math.Round(Convert.ToDouble(rat.TotaalAantalSterren) / Convert.ToDouble(rat.AantalBeoordeeld), 0, MidpointRounding.AwayFromZero).ToString();
            }
            else
            {
                // if rendering the widget for the first time there is no result
                ratingModel.avg = "-1";
            }

            ratingModel.mediaObjectId = mediaObjectId;

            return ratingModel;
        }

        public void Add(string userRating, int mediaObjectId, string ip)
        {
            int rating = Convert.ToInt32(userRating);
            // Limit values between 1 and 5
            if ((rating > 0) && (rating < 6))
            {
                BEELDBANK_BEOORDEEL ratingObject = new BEELDBANK_BEOORDEEL();

                ratingObject.Score = rating;
                ratingObject.MediaObjectId = mediaObjectId;
                ratingObject.Ip = ip;
                ratingObject.Tijdstip = DateTime.Now;

                db.BEELDBANK_BEOORDEELs.InsertOnSubmit(ratingObject);
                Save();
            }
        }

        public void Save()
        {
            db.SubmitChanges();
        }
    }
}